﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Schema;
using System.Xml.Serialization;
using CommerceML.Version205;
using IBS;
using EdexApiClient;

namespace CommerceML2IBS
{
    public class IntegrationContext
    {
        private string IbsConnectionString { get; set; }
        private IbsDataContext db { get; set; }

        public IntegrationContext(string IbsConnectionString)
        {
            this.IbsConnectionString = IbsConnectionString;
            this.db = new IbsDataContext(this.IbsConnectionString);
        }

        public void Process(string xmlData)
        {
            this.Process(xmlData, null);
        }

        public void Process(string xmlData, SaleOrder defaultDocument)
        {
            var data = this.GetCommerceML(xmlData);
            data.Items.ToList().ForEach(r =>
            {
                if (r is Документ)
                    this.ProcessDocument((Документ)r, defaultDocument);
                if (r is Каталог)
                    this.ProcessCatalog((Каталог)r);
                if (r is ПакетПредложений)
                    this.ProcessPackage((ПакетПредложений)r);
            });
        }

        private void ProcessDocument(Документ entity, SaleOrder defaultDocument)
        {
            try
            {
                var document = new IBS.SaleOrder();
                document.OUTER_KEY = Guid.Parse(entity.Ид);
                document.DOC_DATE = entity.Дата;
                document.DOC_NUMBER = entity.Номер;
                document.TOTAL_AMOUNT = entity.Сумма;
                document.LINECOUNT = entity.Товары.Count();
                document.NOTE = String.IsNullOrEmpty(entity.Комментарий) ? String.Empty : entity.Комментарий;
                document.TAX_AMOUNT = 0;
                /// Получатель
                if (entity.Контрагенты.Any(r => r.Роль == РольТип.Покупатель))
                {
                    var store = entity.Контрагенты.SingleOrDefault(r => r.Роль == РольТип.Покупатель).Склад;
                    document.LOCATION_KEY = int.Parse(store.Ид);
                }
                else
                {
                    throw new Exception("Не указан Покупатель");
                }
                /// Поставщик
                if (entity.Контрагенты.Any(r => r.Роль == РольТип.Продавец))
                {
                    var supplier = entity.Контрагенты.SingleOrDefault(r => r.Роль == РольТип.Продавец);
                    //document.SupplierId = db.GetSupplierByGuid(Guid.Parse(supplier.Ид)).ID_Record;
                    document.COMPANY_KEY = int.Parse(supplier.Ид);
                }
                else
                {
                    throw new Exception("Не указан поставщик");
                }
                /// Позиции
                /// 
                document.SaleOrderItems = entity.Товары.Select(r =>
                {
                    var item = new IBS.SaleOrderLine();
                    item.ITEM_KEY = long.Parse(r.Ид);
                    item.PRICE = r.ЦенаЗаЕдиницу;
                    item.ACTUAL_PRICE = 0; //подставляется в процедуре
                    item.QUANTITY = r.Количество;

                    /// С налогами пока не понятно
                    /// нужны примеры
                    /// item.TaxPercent = r.Налоги                    /// 

                    //item.DISCOUNT = r.
                    //item.TOTAL = r.

                    return item;
                }).ToList();

                var doc_id = db.SaveSaleOrder(document);
                //EdexClient.API_SESSION session = new API_SESSION();
                //string pathString = "http://localhost:1953/edex/";
                //var edex = new EdexClient.EdexContext(pathString);
                //session = edex.GetSession("tnk@tnk.ru", "12345");
                //edex.ChangeCompany("E4EFEE0D-0162-4FE8-B3A8-22DFFDDBA32B", session.APIKEY); //PETROL  
                //session = edex.GetSession("tnk@tnk.ru", "12345");
                //edex.SetIncomingNumber(document.OUTER_KEY, doc_id.ToString(), session.APIKEY);

            }
            catch (Exception ex)
            {
            }
        }
        
        private void ProcessCatalog(Каталог entity) { }

        private void ProcessPackage(ПакетПредложений entity) { }

        private CommerceML.Version205.КоммерческаяИнформация LoadCommerceML(string path)
        {
            // Set the validation settings.
            XmlReaderSettings settings = new XmlReaderSettings();
            settings.ValidationType = ValidationType.Schema;
            settings.ValidationFlags |= XmlSchemaValidationFlags.ProcessInlineSchema;
            settings.ValidationFlags |= XmlSchemaValidationFlags.ProcessSchemaLocation;
            settings.ValidationFlags |= XmlSchemaValidationFlags.ReportValidationWarnings;
            settings.ValidationEventHandler += new ValidationEventHandler(ValidationCallBack);
            // Create the XmlReader object.
            XmlReader reader = XmlReader.Create(path, settings);
            XmlSerializer serializer = new XmlSerializer(typeof(CommerceML.Version205.КоммерческаяИнформация));
            var sd = (CommerceML.Version205.КоммерческаяИнформация)serializer.Deserialize(reader);
            reader.Close();
            return sd;
        }

        public CommerceML.Version205.КоммерческаяИнформация GetCommerceML(string xmlData)
        {
            //using (var reader = System.Xml.XmlReader.Create(uri))
            using (var reader = System.Xml.XmlReader.Create(new System.IO.StringReader(xmlData)))
            {
                var serializer
                    = new System.Xml.Serialization.XmlSerializer(typeof(CommerceML.Version205.КоммерческаяИнформация));
                return (CommerceML.Version205.КоммерческаяИнформация)serializer.Deserialize(reader);
            }
        }

        // Display any warnings or errors.
        private static void ValidationCallBack(object sender, ValidationEventArgs args)
        {
            if (args.Severity == XmlSeverityType.Warning)
                Console.WriteLine("\tWarning: Matching schema not found.  No validation occurred." + args.Message);
            else
                Console.WriteLine("\tValidation error: " + args.Message);
        }        
    }
}
